#ifndef _MODEL_H_
#define _MODEL_H_

#include <glm/glm.hpp>
#include <SERender/Entity/Drawable.h>
#include <vector>
// #include <SEngine/Render/Entity/BoundingGraphics.h>
#include <SEngine/Render/Entity/MeshFilter.h>
#include <SERender/Renderer/Renderer.h>
#include <SEngine/Render/Entity/MaterialFilter.h>
#include <SECore/Serializable.h>

namespace SEngine
{
    class ModelLoader;
    class Model
    {
    public:
        ENABLE_SERIALIZE(Model)
        
        friend class ModelLoader;
    public:
        // void SetBoundingGraphics(std::unique_ptr<BoundingGraphics> && bounding) { m_boundingGraphics = std::move(bounding); }
        // std::unique_ptr<BoundingGraphics> & GetBoundingGraphics() { return m_boundingGraphics; }
        void Transfrom(glm::mat4 model);
        glm::mat4 Transfrom();

        void SetMode(ElemMode mode) { m_renderOpt.mode = mode; }
        void SetAPIType(DrawAPIType type) { m_renderOpt.api = type; }
        void SetInstanceCount(size_t count) { m_renderOpt.instanceCount = count; }
        RenderOption GetRenderOption() { return m_renderOpt; }
        void SetRenderOption(RenderOption opt) { m_renderOpt = opt; }

        void SetMeshFilter(ResRef<MeshFilter> meshes, ResRef<Material> material);
        ResRef<MeshFilter> GetMeshFilter() { return m_meshFilter; }
        void ForeachMaterialFilter(std::function<void(std::string, ResRef<Material>&)> && fn);
        void SetMaterial(const std::string & name, ResRef<Material> material);

        void Draw(Renderer & renderer);
        void Draw(Renderer & renderer, ResRef<Material> material);
        void Draw(Renderer & renderer, ResRef<Shader> shader);

        void Reset();
    private:
        // std::unique_ptr<BoundingGraphics> m_boundingGraphics;
        ResRef<MeshFilter> m_meshFilter;
        std::unordered_map<std::string, ResRef<Material>> m_materials;
        glm::mat4 m_modelMatrix{1.0f};

        RenderOption m_renderOpt;
    };
    
} // namespace SEngine

#endif